﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using Common;
using Model;

namespace AcceptServer.Service
{
    public class OperateCmdData
    {

        public byte[] AnalysisMessageId(byte[] realData, IPAddress clientIp)
        {
            ushort messageId = OperateAgreement.GetMessageIdInMessageHead(realData);
            // Console.WriteLine(messageId);
            byte[] sendData = new byte[1];
            switch (messageId)
            {
                case ConstParameters.CmdGetNearbyBus:
                    {
                        sendData = GetNearbyBusInfoData(realData);
                        break;
                    }
                case ConstParameters.CmdGetAllBus:
                    {
                        sendData = GetNearbyBusInfoData(realData);
                        break;
                    }
                case ConstParameters.CmdGetClientVersion:
                    {
                        sendData = GetClientVersionInfoData(realData);
                        break;
                    }
                case ConstParameters.CmdGetControlCardConfig:
                    {
                        sendData = GetControlCardConfig();
                        break;
                    }


            }
            return sendData;
        }

        public byte[]GetClientVersionInfoData(byte[] realData)
        {
            double version = 1.0;
            string config = OperateConfig.GetTheNewestClientVersion();
            double.TryParse(config, out version);
            byte[] messageBody = BitConverter.GetBytes(version);

            byte[] messageHead = OperateAgreement.GetMessageHead(ConstParameters.CmdGetClientVersionReply,
                false,false,messageBody.Length, new byte[6], new byte[2],
                                                 1,1);
            List<byte> messageDatas = new List<byte>();
            messageDatas.AddRange(OperateAgreement.PackageSendData(messageHead, messageBody.ToArray()));
            return messageDatas.ToArray();
        }

        /// <summary>
        /// Add 3 byte
        /// </summary>
        /// <param name="realData"></param>
        /// <param name="type">0---Taxi,1---PhoneUser</param>
        public byte[] GetNearbyBusInfoData(byte[] realData)
        {
            try
            {

                List<BusInfo> taxiInfos = new List<BusInfo>();
                const ushort taxiCount = ConstParameters.MaxTaxiInfoInOneMessage;
                ushort messageId = OperateAgreement.GetMessageIdInMessageHead(realData);

                ushort messageidreply;
                if (messageId == ConstParameters.CmdGetNearbyBus)
                {
                    messageidreply = ConstParameters.CmdGetNearbyBusReply;

                    #region Get ReceData Infomation


                    // Max carinfo in one Command (Must less than 23)
                    byte[] tempData = new byte[5];
                    Array.Copy(realData, ConstParameters.MBodySatrtIndex, tempData, 0, 5);
                    double longitude = double.Parse(CommonRoutine.ByteToBcdString(tempData)) / 1000000;
                    Array.Copy(realData, ConstParameters.MBodySatrtIndex + 5, tempData, 0, 5);
                    double latitude = double.Parse(CommonRoutine.ByteToBcdString(tempData)) / 1000000;
                    int distance = realData[27];

                    //byte[] phoneNumberbyts = new byte[6];
                    //Array.Copy(realData, 5, phoneNumberbyts, 0, 6);
                    //byte[] serialNumber = new byte[2];
                    //Array.Copy(realData, 11, serialNumber, 0, 2);

                    #endregion
                    // get Nearby TaxiIfo
                    taxiInfos = GetNearbyGps(longitude, latitude, distance);
                }
                else
                {
                    messageidreply = ConstParameters.CmdGetAllBusReply;
                    taxiInfos = GetAllBus();
                }


                ushort cmdCount = Convert.ToUInt16(taxiInfos.Count / taxiCount);
                if (taxiInfos.Count % taxiCount == 0 && cmdCount > 0)
                {
                    cmdCount--;
                }
                int tempTaxiIndex = 0;
                List<byte> messageDatas = new List<byte>();
                Console.WriteLine("一共有" + taxiInfos.Count + "辆车。");

                for (ushort i = 0; i <= cmdCount; i++)
                {
                    List<byte> messageBody = new List<byte>();
                    ushort j = 0;
                    if (taxiInfos.Count > 0)
                    {
                        for (; j < taxiCount; j++)
                        {
                            if (tempTaxiIndex < taxiInfos.Count)
                            {
                                #region add TaxiInfo to Data

                                BusInfo taxiInfo = taxiInfos[tempTaxiIndex];
                                //longitude 5
                                string longitudestr =
                                    ((taxiInfo.Longitude * Math.Pow(10, 6)).ToString().PadLeft(10, '0'));
                                byte[] longitudeBytes = CommonRoutine.BcdStringToBytes(longitudestr);
                                messageBody.AddRange(longitudeBytes);
                                //latitude 5
                                string latitudestr =
                                    (taxiInfo.Latitude * Math.Pow(10, 6)).ToString().PadLeft(10, '0');

                                byte[] latitudeBytes = CommonRoutine.BcdStringToBytes(latitudestr);
                                messageBody.AddRange(latitudeBytes);

                                //TaxiNo 8
                                byte[] taxiNobytes = new byte[8];

                               // taxiInfo.BusName = "一路";
                                byte[] tempTaxiNobytes = Encoding.GetEncoding("GBK").GetBytes(taxiInfo.BusName);
                                for (int k = 0; k < taxiNobytes.Length; k++)
                                {
                                    if (k < tempTaxiNobytes.Length)
                                    {
                                        taxiNobytes[k] = tempTaxiNobytes[k];
                                    }
                                    else
                                    {
                                        taxiNobytes[k] = 32;
                                    }
                                }
                                messageBody.AddRange(taxiNobytes);
                                byte[] angle = BitConverter.GetBytes(taxiInfo.Angle);
                                messageBody.AddRange(angle);
                                messageBody.Add(taxiInfo.Speed);

                                byte[] IMEIbytes = CommonRoutine.BcdStringToBytes(taxiInfo.IMEI);

                                messageBody.AddRange(IMEIbytes);
                                string timeStr = taxiInfo.UpdateTime.ToString("yyyyMMddHHmmss");

                                byte[] timebytes = Encoding.GetEncoding("GBK").GetBytes(timeStr);


                                messageBody.AddRange(timebytes);



                                byte[] taxiPreStation = new byte[20];
                                byte[] tempTaxiPreStation= Encoding.GetEncoding("GBK").GetBytes(taxiInfo.PreStation);
                                for (int k = 0; k < taxiPreStation.Length; k++)
                                {
                                    if (k < tempTaxiPreStation.Length)
                                    {
                                        taxiPreStation[k] = tempTaxiPreStation[k];
                                    }
                                    else
                                    {
                                        taxiPreStation[k] = 32;
                                    }
                                }

                                messageBody.AddRange(taxiPreStation);


                                byte[] taxiCurrentStation = new byte[20];
                                byte[] tempTaxiCurrentStation = Encoding.GetEncoding("GBK").GetBytes(taxiInfo.CurrentStation);
                                for (int k = 0; k < taxiCurrentStation.Length; k++)
                                {
                                    if (k < tempTaxiCurrentStation.Length)
                                    {
                                        taxiCurrentStation[k] = tempTaxiCurrentStation[k];
                                    }
                                    else
                                    {
                                        taxiCurrentStation[k] = 32;
                                    }
                                }

                                messageBody.AddRange(taxiCurrentStation);




                                #endregion
                                tempTaxiIndex++;

                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    byte[] taxiCountBytes = BitConverter.GetBytes(j);
                    foreach (var taxiCountByte in taxiCountBytes)
                    {
                        messageBody.Insert(0, taxiCountByte);
                    }
                    bool isSubPackage;
                    ushort packgeCounts;
                    ushort packageIndex;
                    if (taxiInfos.Count == 0 || cmdCount == 0)
                    {
                        isSubPackage = false;
                        packgeCounts = 1;
                        packageIndex = 1;
                    }
                    else
                    {
                        isSubPackage = true;
                        packgeCounts = (ushort)(cmdCount + 1);
                        packageIndex = (ushort)(i + 1);
                    }



                    byte[] messageHead = OperateAgreement.GetMessageHead(messageidreply, isSubPackage,
                                                        false, messageBody.Count, new byte[6], new byte[2],
                                                    packgeCounts, packageIndex);

                    messageDatas.AddRange(OperateAgreement.PackageSendData(messageHead, messageBody.ToArray()));
                }

                return messageDatas.ToArray();
            }
            catch (Exception ex)
            {
                CommonRoutine.HandlingExceptions(ex);
                return null;
            }

        }




        public List<BusInfo> GetAllBus()
        {


            lock (AcceptMainForm.BusiList.SyncRoot)
            {

                List<BusInfo> taxiInfos = AcceptMainForm.BusiList.Values.Cast<BusInfo>().ToList();
                return taxiInfos;
            }

            #region Test Method 2
            //List<TaxiInfo> taxiInfos = new List<TaxiInfo>();
            //foreach (TaxiInfo taxiInfo in MainForm.TaxiList.Values)
            //{
            //    //if (Common.CommonRoutine.GetShortDistance(longitude, latitude, taxiInfo.Longitude, taxiInfo.Latitude) <= distance)
            //    //{
            //    //    taxiInfos.Add(taxiInfo);
            //    //}
            //    if (Math.Abs(taxiInfo.Latitude - latitude) < distance && Math.Abs(taxiInfo.Longitude - longitude) < distance)
            //    {
            //        taxiInfos.Add(taxiInfo);
            //    }
            //}
            #endregion
        }

        public List<BusInfo> GetNearbyGps(double longitude, double latitude, double distance)
        {
            double d = distance * 2 / 100.0f;
            double d2 = d;

            lock (AcceptMainForm.BusiList.SyncRoot)
            {

                List<BusInfo> taxiInfos = new List<BusInfo>();



                taxiInfos.AddRange(AcceptMainForm.BusiList.Values.Cast<BusInfo>().
                        Where(taxiInfo => Math.Abs(taxiInfo.Latitude - latitude) < d
                            && Math.Abs(taxiInfo.Longitude - longitude) < d2));


                return taxiInfos;
            }
            #region Test Method 2
            //List<TaxiInfo> taxiInfos = new List<TaxiInfo>();
            //foreach (TaxiInfo taxiInfo in MainForm.TaxiList.Values)
            //{
            //    //if (Common.CommonRoutine.GetShortDistance(longitude, latitude, taxiInfo.Longitude, taxiInfo.Latitude) <= distance)
            //    //{
            //    //    taxiInfos.Add(taxiInfo);
            //    //}
            //    if (Math.Abs(taxiInfo.Latitude - latitude) < distance && Math.Abs(taxiInfo.Longitude - longitude) < distance)
            //    {
            //        taxiInfos.Add(taxiInfo);
            //    }
            //}
            #endregion
        }




        public byte[] GetControlCardConfig()
        {
            List<byte> mbodydata = new List<byte>();


            string[] configs = OperateConfig.GetControlCardConfig();
            string[] config_in = configs[0].Split(',');
            char[] config_out = configs[1].ToCharArray();

            foreach (string s in config_in)
            {
                mbodydata.Add(byte.Parse(s));
            }
            foreach (char c in config_out)
            {
                mbodydata.Add(byte.Parse(c.ToString()));
            }
            byte[] mHead =OperateAgreement.GetMessageHead(ConstParameters.CmdGetControlCardConfigReply, false, false, mbodydata.Count, new byte[6],
                              new byte[2], 0, 0);
            byte[] tempData1 = OperateAgreement.PackageSendData(mHead, mbodydata.ToArray());
            return tempData1;
        }




    }
}
